package com.itlong.cloud.sdk.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.IotCloudElevatorStateDTO;
import com.itlong.cloud.POJO.DTO.sdk.*;
import com.itlong.cloud.POJO.DTO.sdk.jd.JDPassRecordDTO;
import com.itlong.cloud.POJO.PO.DeviceElevatorFloorConfigPO;
import com.itlong.cloud.POJO.PO.DeviceElevatorInfoPO;
import com.itlong.cloud.POJO.PO.PropertyRoleProjectPO;
import com.itlong.cloud.POJO.PO.SendCallElevatorMessageTaskPO;
import com.itlong.cloud.POJO.VO.common.ProjectIotInfo;
import com.itlong.cloud.POJO.VO.jd.JDCloudElevatorRunStateVO;
import com.itlong.cloud.POJO.VO.jd.JDResultVO;
import com.itlong.cloud.POJO.VO.property.CloudElevatorVO;
import com.itlong.cloud.POJO.VO.sdk.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppDeviceDao;
import com.itlong.cloud.commons.thread.queue.process.queue.SendIotCallElevatorQueue;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.CloudElevatorIotOrderTypeEnum;
import com.itlong.cloud.enumerate.DeviceIotEnum;
import com.itlong.cloud.enumerate.IotCloudCtrlInstructEnum;
import com.itlong.cloud.property.dao.IPropertyEquipDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.sdk.dao.ICloudElevatorSDKRobotDao;
import com.itlong.cloud.sdk.dao.ICloudElevatorSDKServerCloudDao;
import com.itlong.cloud.sdk.service.ICloudElevatorSDKRobotService;
import com.itlong.cloud.sdk.service.ICloudElevatorSDKServerCloudService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.IdWorker;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <desc>
 *      云电梯SDK设备服务接口实现类
 * <desc/>
 *
 * @createDate 2018/12/27
 */
@Service
public class CloudElevatorSDKServerCloudServiceImpl implements ICloudElevatorSDKServerCloudService {
    private static final Logger LOG = LoggerFactory.getLogger(CloudElevatorSDKServerCloudServiceImpl.class);

    @Autowired
    private ICloudElevatorSDKServerCloudDao iCloudElevatorSDKServerCloudDao;

    @Autowired
    private ICloudElevatorSDKRobotDao iCloudElevatorSDKRobotDao;

    @Autowired
    ICloudElevatorSDKRobotService iCloudElevatorSDKRobotService;

    @Autowired
    SendIotCallElevatorQueue sendIotCallElevatorQueue;

    @Autowired
    private IPropertyEquipDao iPropertyEquipDao;

    @Autowired
    RedisService redisService;

    @Autowired
    IAppDeviceDao iAppDeviceDao;

    @Autowired
    MessageSender messageSender;

    @Autowired
    private ICloudElevatorSDKServerCloudService iCloudElevatorSDKServerCloudService;

    final static IdWorker idWorker = new IdWorker(10);
    @Value("${" + PlatformConstants.JD_DOMAIN + "}")
    public String domain ;

    @Value("${" + PlatformConstants.JD_APPID + "}")
    public String appid;
    @Value("${" + PlatformConstants.JD_SECRET + "}")
    public String secret;


    //@Value("${" + PlatformConstants.JD_SECRET + "}")
    //public String secret = "KJYWH5GYYVHABYPXHKE7QDDDA";

//    @Value("${" + PlatformConstants.CLOUD_TALK_SDK_AESKEY + "}")
//    private  String cloudTalkSdkAesKey; //AES加密KEY
//    @Value("${" + PlatformConstants.CLOUD_TALK_SDK_MD5KEY + "}")
//    private  String cloudTalkSdkMd5Key;  //MD5加密KEY
    /**
     * <desc>
     *      初始化
     * </desc>
     *
     * @author Jiaqi.X
     * @createDate 2018/04/10
     */
    @PostConstruct
    public void polling() {
        //初始化线程池
        cachedThreadPool = Executors.newFixedThreadPool(100);
    }

    private ExecutorService cachedThreadPool ; //线程池

    //需要发送状态的项目
    private static Map<String,String> projectIds = new HashMap<>();

    /**
     * <desc>
     *      查询项目下电梯设备唯一码列表
     * </desc>
     *
     * @param cloudElevatorSDKServerGetElevatorPageDTO 云电梯SDK查询项目下电梯设备唯一码列表DTO
     * @return 云电梯SDK查询项目下电梯设备唯一码列表VO
     * @author wangzhi
     * @createDate 2018/12/27
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getElevatorPage(CloudElevatorSDKServerGetElevatorPageDTO cloudElevatorSDKServerGetElevatorPageDTO) throws Exception {
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(cloudElevatorSDKServerGetElevatorPageDTO);
        PropertyRoleProjectPO propertyRoleProjectPO = iCloudElevatorSDKRobotDao.getOriginalProjectInfoByRole4(params);
        List<String> list = null;
        if (propertyRoleProjectPO != null) {
            // 从机器人乘梯API授权设备信息中解析出deviceId
            String deviceAuthCloudElevatorStr = propertyRoleProjectPO.getDeviceAuthCloudElevator();
            if (StringUtils.isNotBlank(deviceAuthCloudElevatorStr)) {
                list = new ArrayList<>();
                int i = deviceAuthCloudElevatorStr.indexOf("1");
                while (i != -1) {
                    int deviceInt = i + 1;
                    String deviceId = StringHandlerUtil.formatStrLen(deviceInt + "", "0", 4, false, false);
                    list.add(cloudElevatorSDKServerGetElevatorPageDTO.getProjectId() + "1" + deviceId);
                    i = deviceAuthCloudElevatorStr.indexOf("1", deviceInt);
                }
            }
        }
        return list;
    }

    /**
     * <desc>
     *      根据设备唯一码查询电梯信息
     * </desc>
     *
     * @return 根据设备唯一码查询电梯信息VO
     * @author wangzhi
     * @createDate 2018/12/28
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<CloudElevatorSDKGetByDeviceUniqueVO> getElevatorInfo(CloudElevatorSDKGetByDeviceUniqueDTO cloudElevatorSDKGetByDeviceUniqueDTO) throws Exception {
        List<String> deviceUniques = StringHandlerUtil.splitStringList(cloudElevatorSDKGetByDeviceUniqueDTO.getDeviceUnique());
        return iCloudElevatorSDKServerCloudDao.getElevatorInfo(deviceUniques);
    }

    /**
     * <desc>
     *      根据设备唯一码查询电梯信息
     * </desc>
     *
     * @return 根据设备唯一码查询电梯信息VO
     * @author Jiaqi.X
     * @createDate 2019/07/17
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<RobotNoninductiveDeviceUniqueVO> getElevatorInfoForRobot(CloudElevatorSDKGetByDeviceUniqueDTO cloudElevatorSDKGetByDeviceUniqueDTO) throws Exception {
        List<String> deviceUniques = StringHandlerUtil.splitStringList(cloudElevatorSDKGetByDeviceUniqueDTO.getDeviceUnique());
        List<RobotNoninductiveDeviceUniqueVO> list = new ArrayList<>();
        if (deviceUniques!=null && !deviceUniques.isEmpty()){
            list=iCloudElevatorSDKServerCloudDao.getElevatorInfoForRobot(deviceUniques);
        }
        return list;
    }

    /**
     * <desc>
     *      发送开门关门指令
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/12/28
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void sendOpenAndCloseDoor(CloudElevatorSDKServerSendCommandDTO cloudElevatorSDKServerSendCommandDTO) throws Exception {
        SendCallElevatorMessageTaskPO send = new SendCallElevatorMessageTaskPO();
        //将开门关门指令放入自定义队列
        sendIotCallElevatorQueue.getSendIotCallElevatorQueue().put(send);
    }

    /**
     * <desc>
     *      根据楼层名称获取真实楼层
     * </desc>
     *
     * @param goFloor
     * @param fromFloor
     * @return
     * @author Jiaqi.X
     * @createDate 2018/01/03
     */
    @Override
    public Map<String, Object> getFloorNumByLogicFloor(String goFloor, String fromFloor,String deviceUnique) {
        return iCloudElevatorSDKServerCloudDao.getFloorNumByLogicFloor(goFloor,fromFloor,deviceUnique);
    }

    /**
     * <desc>
     *      获取上报状态详情
     * </desc>
     *
     * @param appId
     * @param appSecret
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/03
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Map<String,Object> getReportInfo(String appId, String appSecret, String projectId){
        return iCloudElevatorSDKServerCloudDao.getReportInfo(appId, appSecret, projectId);
    }

    /**
     * <desc>
     *      打开关闭上报状态
     * </desc>
     *
     * @param cloudElevatorSDKStateReportDTO
     * @author Jiaqi.X
     * @createDate 2019/01/03
     */
    public void setOpenOrCloseStateReport(CloudElevatorSDKStateReportDTO cloudElevatorSDKStateReportDTO) throws IOException {
        LOG.info("【打开关闭上报状态】"+JsonUtil.toJSON(cloudElevatorSDKStateReportDTO));
        String key = cloudElevatorSDKStateReportDTO.getProjectId()+cloudElevatorSDKStateReportDTO.getAppId();
        //如果状态为关闭，将项目上报状态设置为关闭
        if(cloudElevatorSDKStateReportDTO.getOpenOrClose().equals("2")){
            projectIds.put(key,null);
        }else {
            redisService.set(RedisConstant.CLOUD_ELEVATOR_SERVER_STATE_REPORT_KEY+key,RedisConstant.CLOUD_ELEVATOR_SERVER_STATE_REPORT_CACHE_TIME,
                    cloudElevatorSDKStateReportDTO.getOpenOrClose());
            if (projectIds.get(key) == null) {
                projectIds.put(key,cloudElevatorSDKStateReportDTO.getOpenOrClose());
                //获取设备上报地址及需要上报的设备序列号
                Map<String,Object> result = iCloudElevatorSDKServerCloudDao.getReportInfo(cloudElevatorSDKStateReportDTO.getAppId(),cloudElevatorSDKStateReportDTO.getAppSecret(),
                        cloudElevatorSDKStateReportDTO.getProjectId());
                String auth = result.get("auth")!=null ? result.get("auth").toString():null;
                String deviceUniques;
                //清空缓存
                String deviceIds = StringHandlerUtil.convertAuth(auth,"1");
                deviceUniques = iCloudElevatorSDKServerCloudDao.getElevatorDeviceUniquesByDeviceIds(StringHandlerUtil.splitString(deviceIds),cloudElevatorSDKStateReportDTO.getProjectId());
                LOG.info("【云端推送云电梯状态设备序列号】"+deviceUniques);
                String[] deviceNames = StringHandlerUtil.splitString(deviceUniques);
                for(String deviceName : deviceNames){
                    redisService.delForDevice(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE + deviceName);
                }
                //开启线程 上报状态
                cachedThreadPool.execute(() -> {
                    LOG.info("【云端推送云电梯状态设备信息】"+result);
                    if(result.get("url")!=null){
                        String url = result.get("url").toString();
                        try {
                            while(projectIds.get(key) !=null && redisService.get(RedisConstant.CLOUD_ELEVATOR_SERVER_STATE_REPORT_KEY+key)!=null){
                                List<SDKCloudElevatorRunState> states = this.getCloudElevatorState(deviceUniques);
                                LOG.info("【云端推送云电梯状态】"+JsonUtil.toJSON(states));
                                Map<String,Object> secretMap = new HashMap<>();
                                String createTime = DateUtil.fomatDate(new Date(),"yyyyMMddHHmmss");
                                secretMap.put("states",JsonUtil.toJSON(states));
                                secretMap.put("sign", Md5EncryptUtil.cloudDeviceMd5(secretMap, createTime, result.get("appsecret").toString()));
                                secretMap.put("createTime", createTime);
                                LOG.info(String.format("【SDK上报电梯状态】%s", JsonUtil.toJSON(states)));
                                String encryptResult = DesEncryptUtil.aesEncryptSDK(JsonUtil.toJSON(secretMap), result.get("appsecret").toString());
                                Map<String,Object> params = new HashMap<>();
                                params.put("encryptScript",encryptResult);
                                HttpProtocolUtil.httpPost(url,JsonUtil.toJSON(params));
                                Thread.sleep(1000);
                            }
                            projectIds.put(key,null);
                        } catch (Exception e) {
                            LOG.error("【SDK获取电梯上报状态失败】",e);
                        }
                    }
                });
            }
        }
    }

    /**
     * <desc>
     *      查询群控器的呼梯结果信息
     * </desc>
     *
     * @param robotId
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/07/17
     */
    @Override
    public String getCallInfo(String robotId, String deviceUnique) throws IOException {
        CloudControllerNotifyMessageVO dto =JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_CONTROLLER_NOTIFY_MESSAGE_CACHE +
                deviceUnique+robotId),CloudControllerNotifyMessageVO.class);
        String recordId = redisService.get(RedisConstant.REDIS_ROBOT_NONINDUCTIVE_CALL_RECORD_CACHE + robotId);
        if(StringUtils.isNotBlank(recordId) && dto!=null){
            //更新呼梯记录
            iCloudElevatorSDKServerCloudDao.updateHistoryRecord(recordId,dto.getDeviceUnique());
        }
        return dto != null ? dto.getDeviceUnique() : null;
    }

    /**
     * <desc>
     *      获取电梯实时状态
     * </desc>
     *
     * @param deviceUnique 设备序列号 多个,号分隔
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/10
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<SDKCloudElevatorRunState> getCloudElevatorState(String deviceUnique) throws Exception {
        try {
            //从redis中读取电梯的实时状态
            String[] deviceNames = StringHandlerUtil.splitString(deviceUnique);
            List<SDKCloudElevatorRunState> states = new ArrayList<>();
            //需要发送的控制指令集合
            List<Map<String, Object>> controls = new ArrayList<>();
            List<Map<String,Object>> cmdControls = new ArrayList<>();
            for (String deviceName : deviceNames) {
                CloudElevatorVO elevator;
                try {
                    elevator = iAppDeviceDao.getElevatorNameAndProductKeyByDeviceUnique(deviceName);
                } catch (Exception e) {
                    elevator = null;
                }
                LOG.info(String.format("【获取电梯状态，电梯信息】%s",JsonUtil.toJSON(elevator)));
                if (elevator != null) {
                    System.out.println(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE + deviceName));
                    IotCloudElevatorStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE +
                            deviceName),IotCloudElevatorStateDTO.class);
                    if (StringUtils.isNotBlank(elevator.getIotDeviceId())&&(dto == null || (StringUtils.isNotBlank(dto.getTimeout())))) {
                        if(dto != null && StringUtils.isNotBlank(dto.getTimeout())){
                            //清空该电梯设备缓存
                            redisService.delForDevice(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE + deviceName);
                        }
                        //如果获取的电梯状态为null 或者超时时长有值，需要发送电梯状态上报控制指令
                        if(StringUtils.isBlank(redisService.get(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CTRL_CACHE +
                                deviceName + IotCloudCtrlInstructEnum.DEVICEREPORTCTRL.getUrl()))) {

                            ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceName),deviceName,StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceName));
                            if(projectIotInfo.getIotFlag() == 1) {
                                Map<String, Object> control = new HashMap<>();
                                control.put("productKey", elevator.getIotProductKey());
                                if (StringUtils.isBlank(elevator.getVersion()) ||
                                        Integer.valueOf(elevator.getVersion().substring(elevator.getVersion().indexOf("V") + 1, elevator.getVersion().indexOf("V") + 5)) < 1040) {
                                    JSONObject jsonObject = new JSONObject();
                                    jsonObject.put("timeout", "300");
                                    control.put("message", jsonObject.toJSONString());
                                    control.put("topic", "/" + deviceName + (elevator.getIotVersion() == 1 ? "/user" : "") + IotCloudCtrlInstructEnum.DEVICEREPORTCTRL.getUrl());
                                    controls.add(control);
                                } else {
                                    JSONObject cmd = new JSONObject();
                                    cmd.put("sourceFrom", "itlong");
                                    cmd.put("snr", 0);
                                    cmd.put("cmd", CloudElevatorIotOrderTypeEnum.REPORTCONTROLLER.getType());//1001
                                    JSONObject cmdChildChild = new JSONObject();
                                    cmdChildChild.put("timeout", "300");
                                    cmd.put("data", cmdChildChild);
                                    control.put("message", cmd.toJSONString());
                                    control.put("topic", "/" + deviceName + (elevator.getIotVersion() == 1 ? "/user" : "") + IotCloudCtrlInstructEnum.DEVICECMD.getUrl());
                                    cmdControls.add(control);
                                }
                            }else {
                                //发送上报指令
                                Map<String,Object> data = new HashMap<>();
                                Map<String,Object> message = new HashMap<>();
                                data.put("serviceId","SettingService");
                                data.put("commandName","deviceReportCtrl");
                                data.put("deviceId",projectIotInfo.getHuaweiIotId());
                                message.put("sourceFrom","itlong");
                                message.put("snr", LogicIdUtil.bussinessId());
                                message.put("cmd","1001");
                                message.put("timestamp",DateUtil.addCurrentTime(new Date(),3*60*60*1000).getTime()+"");
                                Date date1 = new Date();
                                Date date2 = Calendar.getInstance().getTime();
                                LOG.info(String.format("【date时间函数】：%s 【时间戳】 %s 【Calendar时间函数】%s 【时间戳】%s",date1,date2,date1.getTime(),date2.getTime()));
                                LOG.info("时区信息:{}", DateUtil.getDetailDateTime());
                                message.put("timeout","300");
                                data.put("message",JsonUtil.toJSON(message));
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put("data",data);
                                messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, jsonObject.toJSONString(),
                                        RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);
                            }
                            redisService.set(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CTRL_CACHE + deviceName + IotCloudCtrlInstructEnum.DEVICEREPORTCTRL.getUrl(),
                                    RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CTRL_CACHE_TIME,"false");
                        }
                    }
                    if(StringUtils.isNotBlank(elevator.getIotDeviceId()) && dto!= null){
                        LOG.info(String.format("【SDK获取云电梯状态】:%s", JsonUtil.toJSON(dto)));
                        //返回获取的云电梯状态
                        SDKCloudElevatorRunState runState = new SDKCloudElevatorRunState();
                        runState.setDeviceUnique(deviceName);
                        runState.setFloorNum(StringUtils.isBlank(elevator.getVersion()) ||
                                Integer.valueOf(elevator.getVersion().substring(elevator.getVersion().indexOf("V") + 1, elevator.getVersion().indexOf("V") + 5)) < 1040
                                ? iAppDeviceDao.getLogicFloorByFloorNum(dto.getFloor(), deviceName) : StringUtils.isNotBlank(dto.getFloor()) && !dto.getFloor().equals("-") ? dto.getFloor() : "-");
                        if(StringUtils.isNotBlank(runState.getFloorNum())) {
                            runState.setDoorStatus(Integer.valueOf(dto.getFrontDoor()));
                            //app状态为 1:上行  2:下行  3:停层  设备上报状态为：1:下行  2:上行 0：停层
                            if (dto.getUpDown().equals("1")) {
                                runState.setFloorStatus("2");
                            } else if (dto.getUpDown().equals("2")) {
                                runState.setFloorStatus("1");
                            } else {
                                runState.setFloorStatus("3");
                            }
                            states.add(runState);
                        }
                    }
                }
            }
            //发送云电梯控制指令
            sendCloudElevatorMessage(controls,cmdControls);
            return states;
        }catch (Exception e){
            LOG.error("【云电梯获取实时状态异常】",e);
            throw e;
        }
    }

    /**
     * <desc>
     *      发布云电梯消息到iot中心
     * </desc>
     *
     * @param messages
     * @author Jiaqi.X
     * @createDate 2018/04/12
     */

    private void sendCloudElevatorMessage(List<Map<String,Object>> messages,List<Map<String,Object>> newMessages) throws Exception {
        LOG.info("【SDK云端查询电梯状态发送云电梯控制指令】messages"+JsonUtil.toJSON(messages));
        LOG.info("【SDK云端查询电梯状态发送云电梯控制指令】newMessages"+JsonUtil.toJSON(newMessages));
        if(!messages.isEmpty()){
            Map<String,Object> params = new HashMap<>();
            params.put("deviceOperateIotType", DeviceIotEnum.PUB_MESSAGE.getCommandType());
            params.put("devices",messages);
            JSONObject obj = new JSONObject();
            obj.put("data",params);
            messageSender.send(RabbitMQConstant.RABBITMQ_IOT_PUB_QUEUE, obj.toJSONString(),
                    RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_IOT_PUB_KEY);
        }
        if(!newMessages.isEmpty()){
            Map<String,Object> params = new HashMap<>();
            params.put("deviceOperateIotType", DeviceIotEnum.PUB_MESSAGE.getCommandType());
            params.put("devices",newMessages);
            JSONObject obj = new JSONObject();
            obj.put("data",params);
            messageSender.send(RabbitMQConstant.RABBITMQ_IOT_PUB_QUEUE, obj.toJSONString(),
                    RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_IOT_PUB_KEY);
        }
    }

    /**
     * <desc>
     *      根据楼层名称获取实际楼层和权限标识
     * </desc>
     *
     * @param floors
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/08/15
     */
    @Override
    public Map<String, Object> getFloorNumAndNaturalFloorByLogicFloor(String floors, String deviceUnique) {
        return iCloudElevatorSDKServerCloudDao.getFloorNumAndNaturalFloorByLogicFloor(StringHandlerUtil.splitString(floors), deviceUnique);
    }

    /**
     * <desc>
     *      查询群控器所绑定的设备
     * </desc>
     *
     * @param controllerDeviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/07/24
     */
    @Override
    public String getDeviceUniqueByControllerDeviceUnique(String controllerDeviceUnique){
        return iCloudElevatorSDKServerCloudDao.getDeviceUniqueByControllerDeviceUnique(controllerDeviceUnique);
    }

    /**
     * <desc>
     *      获取项目下机器人的呼梯记录
     * </desc>
     *
     * @param dto
     * @return
     * @author Jiaqi.X
     * @createDate 2019/07/24
     */
    @Override
    public Page<RobotNoninductiveHistoryRecordVO> getHistoryRecords(RobotNoninductiveHistoryRecordDTO dto) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(dto);
        //分页类默认pageSize为20
        Page<RobotNoninductiveHistoryRecordVO> page = new Page<>();
        page.getPage().setPageSize(dto.getPageSize());
        page.getPage().setCurrentPage(dto.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        page.setRows(iCloudElevatorSDKServerCloudDao.getHistoryRecords(params), iCloudElevatorSDKServerCloudDao.getHistoryRecordsCount(params));
        return page;
    }

    /**
     * <desc>
     *      获取云电梯信息
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Qiang.S
     * @createDate 2020/04/08
     */
    @Override
    public DeviceElevatorInfoPO getElevatorByDeviceUnique(String deviceUnique){
        return iPropertyEquipDao.getElevatorByDeviceUnique(deviceUnique);
    }

    /**
     * <desc>
     * 根据jd设备号获取云电梯信息
     * </desc>
     *
     * @param jdDeviceUnique
     * @return
     * @author caoshuai
     * @createDate 2020/08/03
     */
    @Override
    public DeviceElevatorInfoPO getElevatorByJDDeviceUnique(String jdDeviceUnique) {
        return iPropertyEquipDao.getElevatorByJDDeviceUnique(jdDeviceUnique);
    }

    /**
     * <desc>
     *     获取楼层信息
     * </desc>
     *
     * @param params
     * @return
     * @author caoshuai
     * @createDate 2020/08/05
     */
    @Override
    public List<DeviceElevatorFloorConfigPO> getFloorInfoByMap(Map<String, Object> params) {

        return  iCloudElevatorSDKServerCloudDao.getFloorInfoByMap(params);
    }

    /**
     * <desc>
     * JD打开关闭上报状态
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author caoshuai
     * @createDate 2020/08/10
     */
    @Override
    public JDResultVO jdOpenOrCloseStateReport(String deviceUnique, String openOrClose, String deviceId, String appid, String secret) {
        LOG.info(String.format("【JD打开关闭上报状态】deviceUnique:%s,openOrClose:%s,deviceId:%s", deviceUnique, openOrClose, deviceId));

        Map<Object, Object> deviceStateKey = new HashMap<>(16);
        //"1":开启， "2":关闭
        if(openOrClose.equals("2")){
            deviceStateKey.put(appid,null);
        }else {
            redisService.set(RedisConstant.CLOUD_ELEVATOR_SERVER_STATE_REPORT_KEY +
                            appid,RedisConstant.CLOUD_ELEVATOR_SERVER_STATE_REPORT_CACHE_TIME,
                            openOrClose);

            if(null == deviceStateKey.get(appid) ){
                deviceStateKey.put(appid,openOrClose);
                redisService.delForDevice(RedisConstant.REDIS_IOT_CLOUD_ELEVATOR_STATE_CACHE + deviceUnique);
            }

            //获取电梯设备信息
            DeviceElevatorInfoPO elevatorInfoPO = iCloudElevatorSDKServerCloudService.getElevatorByJDDeviceUnique(deviceId);

//            //开启线程 上报状态
            cachedThreadPool.execute(() -> {
//                LOG.info("【云端推送云电梯状态设备信息】"+result);
                    String url = domain + PlatformConstants.JD_REPORT_RUN_DATA_API;
                    try {
                        while(deviceStateKey.get(appid) !=null && redisService.get(RedisConstant.CLOUD_ELEVATOR_SERVER_STATE_REPORT_KEY + appid)!=null){
                            List<SDKCloudElevatorRunState> states = this.getCloudElevatorState(deviceUnique);
                            List<JDCloudElevatorRunStateVO> jdCloudElevatorRunStateVOS = new ArrayList<>();

                            if(null == states || states.size() < 1){
                                JDCloudElevatorRunStateVO jdCloudElevatorRunStateVO = new JDCloudElevatorRunStateVO();
                                // 电梯当前楼层
                                jdCloudElevatorRunStateVO.setFloor("-");
                                jdCloudElevatorRunStateVO.setUpDown("-");

                                if("1".equals(elevatorInfoPO.getLiftDoorType())){
                                    jdCloudElevatorRunStateVO.setFrontDoor("8");
                                }else {
                                    jdCloudElevatorRunStateVO.setBackDoor("8");
                                }
                                jdCloudElevatorRunStateVOS.add(jdCloudElevatorRunStateVO);
                                //jdCloudElevatorRunStateVO.setDeviceUnique(deviceId);
                            }
                            for (SDKCloudElevatorRunState sdkCloudElevatorRunState : states) {
                                if(deviceUnique.equals(sdkCloudElevatorRunState.getDeviceUnique())){

                                    JDCloudElevatorRunStateVO jdCloudElevatorRunStateVO = new JDCloudElevatorRunStateVO();
                                    // 电梯当前楼层
                                    jdCloudElevatorRunStateVO.setFloor(sdkCloudElevatorRunState.getFloorNum());
                                    // 上下行状态
                                    if(StringUtils.isBlank(sdkCloudElevatorRunState.getFloorStatus())) {
                                        jdCloudElevatorRunStateVO.setUpDown("-");
                                    }else if ("1".equals(sdkCloudElevatorRunState.getFloorStatus())) {
                                        jdCloudElevatorRunStateVO.setUpDown("2");
                                    }else if ("2".equals(sdkCloudElevatorRunState.getFloorStatus())) {
                                        jdCloudElevatorRunStateVO.setUpDown("1");
                                    }else if ("3".equals(sdkCloudElevatorRunState.getFloorStatus())) {
                                        jdCloudElevatorRunStateVO.setUpDown("0");
                                    }else {
                                        jdCloudElevatorRunStateVO.setUpDown("9");
                                    }
                                    //获取电梯设备信息
                                    //DeviceElevatorInfoPO elevatorInfoPO = iCloudElevatorSDKServerCloudService.getElevatorByJDDeviceUnique(deviceUnique);
                                    // 门状态
                                    if("1".equals(elevatorInfoPO.getLiftDoorType())){
                                        if(null == sdkCloudElevatorRunState.getDoorStatus()){
                                            jdCloudElevatorRunStateVO.setFrontDoor("8");
                                        }else {
                                            jdCloudElevatorRunStateVO.setFrontDoor(sdkCloudElevatorRunState.getDoorStatus() + "");
                                        }
                                    }else {
                                        if(null == sdkCloudElevatorRunState.getDoorStatus()){
                                            jdCloudElevatorRunStateVO.setBackDoor("8");
                                        }else {
                                            jdCloudElevatorRunStateVO.setBackDoor(sdkCloudElevatorRunState.getDoorStatus() + "");
                                        }
                                    }
                                    //jdCloudElevatorRunStateVO.setDeviceUnique(deviceId);
                                    jdCloudElevatorRunStateVOS.add(jdCloudElevatorRunStateVO);

                                }

                            }
                            LOG.info(String.format("【JD上报电梯状态】%s", JsonUtil.toJSON(states)));

                            //拼接参数上报信息参数
                            Map<String,Object> paramMap = new HashMap<>();

                            paramMap.put("id", idWorker.nextId() + "");
                            // protocol 参数
                            Map<String, Object> protocol = new HashMap(16);
                            protocol.put("version", PlatformConstants.JD_VERSION);
                            protocol.put("name", PlatformConstants.JD_NAME);
                            // client 参数
                            Map<String, Object> client = new HashMap<>();
                            client.put("appid", appid);
                            paramMap.put("client", client);
                            // params 参数
                            Map params = new HashMap<>(16);
                            Map<Object, Object> data = new HashMap<>(16);
                            //data.put("states", states);
                            params.put("data", jdCloudElevatorRunStateVOS.get(0));
                            params.put("deviceId", deviceId);

                            paramMap.put("protocol", protocol);
                            paramMap.put("client", client);
                            paramMap.put("params", params);

                            Map<String, Object> param = DesEncryptUtil.getJdSign(JSON.toJSONString(paramMap), PlatformConstants.JD_REPORT_RUN_DATA_API, secret);

                            LOG.info(String.format("【上报电梯状态参数】%s", JsonUtil.toJSON(param)));
                            HttpProtocolUtil.httpPost(url,JsonUtil.toJSON(param));
                            Thread.sleep(1000);
                        }
                        deviceStateKey.put(appid,null);
                    } catch (Exception e) {
                        LOG.error("【SDK获取电梯上报状态失败】",e);
                    }

            });

        }
        JDResultVO result = new JDResultVO(200);
        return result;
    }

    /**
     * <desc>
     *      获取云控制器信息
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author caoshuai
     * @createDate 2020/08/05
     */
    @Override
    public SDKDeviceCloudControllerInfoVO getDeviceCloudControllerInfo(String deviceUnique) {
        return  iCloudElevatorSDKServerCloudDao.getDeviceCloudControllerInfo(deviceUnique);
    }

    /**
     * <desc>
     *  查询华为云下群控器所绑定的设备
     * </desc>
     *
     * @param controllerDeviceUnique
     * @return
     * @author caoshuai
     * @createDate 2020/08/10
     */
    @Override
    public String getDeviceUniqueBy(String controllerDeviceUnique) {
        return iCloudElevatorSDKServerCloudDao.getDeviceUniqueBy(controllerDeviceUnique);
    }


    /**
     * <desc>
     *      京东上报通行记录
     * </desc>
     *
     * @param jdPassRecordDTO 京东通行记录VO
     * @return
     * @Author Zhu.yj
     * @createDate  2021/1/11
     */
    @Override
    public void reportPassRecord(JDPassRecordDTO jdPassRecordDTO) throws Exception {
        Map<String,Object> paramMap = new HashMap<>();
        Date nowTime = new Date();
        String url = domain + PlatformConstants.JD_EVENT_REPORT;
        paramMap.put("id", Long.toString(idWorker.nextId()));
        // protocol 参数
        Map<String, Object> protocol = new HashMap(16);
        protocol.put("version", PlatformConstants.JD_VERSION);
        protocol.put("name", PlatformConstants.JD_NAME);
        // client 参数
        Map<String, Object> client = new HashMap<>();
        client.put("appid", appid);
        paramMap.put("client", client);
        // params 参数
        Map<String, Object> params = new HashMap<>(16);
        Map<Object, Object> args = new HashMap<>(16);
        args.put("openId", jdPassRecordDTO.getUserId());
        args.put("passTime", jdPassRecordDTO.getPassTime());
        args.put("passType", jdPassRecordDTO.getPassType());
        args.put("photoUrl", jdPassRecordDTO.getImageStr());
        args.put("photoType", jdPassRecordDTO.getImageType());

        params.put("args", args);
        params.put("deviceId", jdPassRecordDTO.getDeviceId());
        params.put("event", "passRecord");
        params.put("eventTime", nowTime.getTime());

        paramMap.put("protocol", protocol);
        paramMap.put("client", client);
        paramMap.put("params", params);

        try{
            Map<String, Object> param = DesEncryptUtil.getJdSign(JSON.toJSONString(paramMap), PlatformConstants.JD_EVENT_REPORT, secret);
            LOG.info(String.format("【上报通行记录参数】%s", JsonUtil.toJSON(param)));
//            调试期间暂时注掉
            String result = HttpProtocolUtil.httpPost(url,JsonUtil.toJSON(param));
            LOG.info("【上报通行记录参数返回结果】:" + result);
        }catch (Exception e){
            LOG.info("【上报通行记录异常】", e);
        }

    }
}
